using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public partial class Player
{
    public GameObject eduWinObj;
    
    public bool moveSlow { get; set; }

    /// <summary>
    /// whether reach the end
    /// </summary>
    public bool achieved { get; set; }
    public bool triggerWater { get; set; }
    
    private float m_MoveHor;
    public float moveHorFactor = .5f;
    public float moveForwardValue;
    public void MoveForward()
    {
        m_CtrlMoveVec = transform.forward;
        moveForwardValue = 1;
        
        //GameDebug.LogError($"pl;");

        runAnim = roleAnim.animator.GetFloat("RunAnim");
    }

    public float runAnim { get; set; }
    public void OptMove(Vector3 vec)
    {
        if (achieved || mBattleController.gameEnd) return;
        
        m_MoveHor = vec.x * moveHorFactor;
    }

    public void OptStop()
    {
        m_MoveHor = 0;
    }

    /// <summary>
    /// stop move
    /// </summary>
    public override  void StopMove()
    {
        base.StopMove();

        this.Rigidbody.velocity = Vector3.zero;

        m_CtrlMoveVec = Vector3.zero;
        moveForwardValue = 0;
    }

    private float m_Height;
    public float height
    {
        get
        {
            return m_Height;
        }
    }

    public void UpdateHeight(float value, bool anim)
    {
        m_Height = value;
        var localScale = transform.localScale;
        localScale.y = m_Height / 100f;
        if (anim)
        {
            var center = localScale;
            center.y = transform.localScale.y + (localScale.y - transform.localScale.y) * 3;

            TransformAnim.ScaleTo(transform, center, .15f,
                () => { TransformAnim.ScaleTo(transform, localScale, .15f, null); });
        }
        else
        {
            transform.localScale = localScale;
        }
    }
    
    private float m_Weight;
    public float weight
    {
        get
        {
            return m_Weight;
        }
    }

    public void UpdateWeight(float value, bool anim)
    {
        m_Weight = value;
        var localScale = transform.localScale;

        float scale = value / 50 * 1.63f;
        localScale.z =  localScale.x = scale;
        if (anim)
        {
            var center = localScale;
            center.z = center.x = transform.localScale.x + (localScale.x - transform.localScale.x) * 3;
            center.y *= 0.8f;

            TransformAnim.ScaleTo(transform, center, .15f,
                () => { TransformAnim.ScaleTo(transform, localScale, .15f, null); });
        }
        else
        {
            transform.localScale = localScale;
        }
    }
    private int m_Income;
    public int income
    {
        get
        {
            return m_Income;
        }
        set
        {

            if (this.incomeText)
                this.incomeText.text = "$" + value;
            
            m_Income = value;
        }
    }
    private float m_EduScore;
    public float eduScore
    {
        get
        {
            return m_EduScore;
        }
        set
        {
            if (this.scoreText)
                this.scoreText.text = ""+value;
            
            m_EduScore = value;
        }
    }

    void UpdateEduScore(float value)
    {
        StartCoroutine(IESetScore(value));
    }
    
    IEnumerator IESetScore(float targetValue)
    {
        float timer = 0;
        float time = .2f;
        float curValue = this.eduScore;
        while (timer < time)
        {
            timer += Time.deltaTime;
            yield return 0;

            this.eduScore = (int)(Mathf.Lerp(curValue, targetValue,timer/time));
        }

        this.eduScore = targetValue;
    }

    
    public void AddHeight(float add)
    {
        UpdateHeight(height + add,true);

        if (add > 0)
        {
            score += 5;
        }
    }
    public void AddWeight(float add)
    {
        UpdateWeight(weight + add,true); 
        
        if (add > 0)
        {
            score += 5;
        }
    } 
    public void AddIncome(int add)
    {
        income += add; 
        
        mBattleController.IGameBattleController.AddValueToast((int)add);
        
        if (add > 0)
        {
            score += 5;
        }
    } 
    public void AddEduScore(float add)
    {
        this.UpdateEduScore(eduScore + add); 
        
        if (add > 0)
        {
            score += 5;
        }
    }
    public void OnWinPrepare()
    {
        //GameDebug.Log($"player OnWin");

        if (achieved) return;
        
        achieved = true;
        
        StopMove();

        InputActionSign(MActionStateType.win);
    }


    int m_Multi = -1;
    public int multi => m_Multi;
    /// <summary>
    /// get multi reward at end of level
    /// </summary>
    /// <param name="multi"></param>
    /// <param name="trigger"></param>
    public void OnWinMultiReward(int multi)
    {
        if (m_Multi < multi)
        {
            this.m_Multi = multi;

            GameDebug.LogShowy($"get:{multi} multiple rewards");
            
            DoActionDelay.DelayAction(1, () =>
            {
                    if (Game.Instance && Game.Instance.gameSetting.vibration)
                        MoreMountains.NiceVibrations.MMVibrationManager.Haptic(MoreMountains.NiceVibrations.HapticTypes.Success);

                    StartCoroutine(PlayCoinAnim(multi * 10, transform.position));
            });
        }
        this.InputActionSign(MActionStateType.win);
    }

    /// <summary>
    /// play get coin anim
    /// </summary>
    /// <param name="num"></param>
    /// <param name="position"></param>
    /// <returns></returns>
    System.Collections.IEnumerator PlayCoinAnim(int num, Vector3 position)
    {
        for (int i = 0; i < num; i++)
        {
            GameObject pref = GameResourceManager.Load<GameObject>(GameResourceManager.coinPath);
            if (pref)
            {
                var coin = Instantiate(pref, transform.parent);
                coin.transform.position = position;
                coin.gameObject.AddComponent<DelayDestroy>();

                var randPos = position + new Vector3(UnityEngine.Random.Range(-1.25f, 1.25f), 2, UnityEngine.Random.Range(-1.25f, 1.25f));
                TransformAnim.MoveTo(coin.transform, randPos, .8f, () =>
                {
                    DoActionDelay.DelayAction(UnityEngine.Random.Range(.1f, .22f), () =>
                    {
                        if (this)
                        {
                            var targetPos = position + new Vector3(UnityEngine.Random.Range(-2, 2), 10, UnityEngine.Random.Range(-2, 2));

                            TransformAnim.MoveTo(coin.transform, targetPos, 1f, () => { Destroy(coin.gameObject); });
                        }
                    });
                });

                if (i % 5 == 0)
                    yield return null;
            }
        }
    }

    //public override bool isBlowable => curAction.stateId == MActionStateType.battle;
    public void AdjustDir(Vector3 dir)
    {
        if (Mathf.Abs(dir.z) > Mathf.Abs(dir.x))
        {
            if(dir.z > 0)
                transform.localRotation = Quaternion.Euler(0,0,0);
        }
        else
        {
            if(dir.x > 0)
                transform.localRotation = Quaternion.Euler(0,90,0);
            else
                transform.localRotation = Quaternion.Euler(0,-90,0);
        }
    }

}